{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "colab_type": "text",
    "id": "view-in-github"
   },
   "source": [
    "<a href=\"https://colab.research.google.com/github/PacktPublishing/Modern-Computer-Vision-with-PyTorch/blob/master/Chapter10/crowd_counting.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 1000,
     "resources": {
      "http://localhost:8080/nbextensions/google.colab/files.js": {
       "data": "Ly8gQ29weXJpZ2h0IDIwMTcgR29vZ2xlIExMQwovLwovLyBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgovLyBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKLy8KLy8gICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKLy8KLy8gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQovLyBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KLy8gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAovLyBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KCi8qKgogKiBAZmlsZW92ZXJ2aWV3IEhlbHBlcnMgZm9yIGdvb2dsZS5jb2xhYiBQeXRob24gbW9kdWxlLgogKi8KKGZ1bmN0aW9uKHNjb3BlKSB7CmZ1bmN0aW9uIHNwYW4odGV4dCwgc3R5bGVBdHRyaWJ1dGVzID0ge30pIHsKICBjb25zdCBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogIGVsZW1lbnQudGV4dENvbnRlbnQgPSB0ZXh0OwogIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHN0eWxlQXR0cmlidXRlcykpIHsKICAgIGVsZW1lbnQuc3R5bGVba2V5XSA9IHN0eWxlQXR0cmlidXRlc1trZXldOwogIH0KICByZXR1cm4gZWxlbWVudDsKfQoKLy8gTWF4IG51bWJlciBvZiBieXRlcyB3aGljaCB3aWxsIGJlIHVwbG9hZGVkIGF0IGEgdGltZS4KY29uc3QgTUFYX1BBWUxPQURfU0laRSA9IDEwMCAqIDEwMjQ7CgpmdW5jdGlvbiBfdXBsb2FkRmlsZXMoaW5wdXRJZCwgb3V0cHV0SWQpIHsKICBjb25zdCBzdGVwcyA9IHVwbG9hZEZpbGVzU3RlcChpbnB1dElkLCBvdXRwdXRJZCk7CiAgY29uc3Qgb3V0cHV0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG91dHB1dElkKTsKICAvLyBDYWNoZSBzdGVwcyBvbiB0aGUgb3V0cHV0RWxlbWVudCB0byBtYWtlIGl0IGF2YWlsYWJsZSBmb3IgdGhlIG5leHQgY2FsbAogIC8vIHRvIHVwbG9hZEZpbGVzQ29udGludWUgZnJvbSBQeXRob24uCiAgb3V0cHV0RWxlbWVudC5zdGVwcyA9IHN0ZXBzOwoKICByZXR1cm4gX3VwbG9hZEZpbGVzQ29udGludWUob3V0cHV0SWQpOwp9CgovLyBUaGlzIGlzIHJvdWdobHkgYW4gYXN5bmMgZ2VuZXJhdG9yIChub3Qgc3VwcG9ydGVkIGluIHRoZSBicm93c2VyIHlldCksCi8vIHdoZXJlIHRoZXJlIGFyZSBtdWx0aXBsZSBhc3luY2hyb25vdXMgc3RlcHMgYW5kIHRoZSBQeXRob24gc2lkZSBpcyBnb2luZwovLyB0byBwb2xsIGZvciBjb21wbGV0aW9uIG9mIGVhY2ggc3RlcC4KLy8gVGhpcyB1c2VzIGEgUHJvbWlzZSB0byBibG9jayB0aGUgcHl0aG9uIHNpZGUgb24gY29tcGxldGlvbiBvZiBlYWNoIHN0ZXAsCi8vIHRoZW4gcGFzc2VzIHRoZSByZXN1bHQgb2YgdGhlIHByZXZpb3VzIHN0ZXAgYXMgdGhlIGlucHV0IHRvIHRoZSBuZXh0IHN0ZXAuCmZ1bmN0aW9uIF91cGxvYWRGaWxlc0NvbnRpbnVlKG91dHB1dElkKSB7CiAgY29uc3Qgb3V0cHV0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKG91dHB1dElkKTsKICBjb25zdCBzdGVwcyA9IG91dHB1dEVsZW1lbnQuc3RlcHM7CgogIGNvbnN0IG5leHQgPSBzdGVwcy5uZXh0KG91dHB1dEVsZW1lbnQubGFzdFByb21pc2VWYWx1ZSk7CiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXh0LnZhbHVlLnByb21pc2UpLnRoZW4oKHZhbHVlKSA9PiB7CiAgICAvLyBDYWNoZSB0aGUgbGFzdCBwcm9taXNlIHZhbHVlIHRvIG1ha2UgaXQgYXZhaWxhYmxlIHRvIHRoZSBuZXh0CiAgICAvLyBzdGVwIG9mIHRoZSBnZW5lcmF0b3IuCiAgICBvdXRwdXRFbGVtZW50Lmxhc3RQcm9taXNlVmFsdWUgPSB2YWx1ZTsKICAgIHJldHVybiBuZXh0LnZhbHVlLnJlc3BvbnNlOwogIH0pOwp9CgovKioKICogR2VuZXJhdG9yIGZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCBiZXR3ZWVuIGVhY2ggYXN5bmMgc3RlcCBvZiB0aGUgdXBsb2FkCiAqIHByb2Nlc3MuCiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dElkIEVsZW1lbnQgSUQgb2YgdGhlIGlucHV0IGZpbGUgcGlja2VyIGVsZW1lbnQuCiAqIEBwYXJhbSB7c3RyaW5nfSBvdXRwdXRJZCBFbGVtZW50IElEIG9mIHRoZSBvdXRwdXQgZGlzcGxheS4KICogQHJldHVybiB7IUl0ZXJhYmxlPCFPYmplY3Q+fSBJdGVyYWJsZSBvZiBuZXh0IHN0ZXBzLgogKi8KZnVuY3Rpb24qIHVwbG9hZEZpbGVzU3RlcChpbnB1dElkLCBvdXRwdXRJZCkgewogIGNvbnN0IGlucHV0RWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlucHV0SWQpOwogIGlucHV0RWxlbWVudC5kaXNhYmxlZCA9IGZhbHNlOwoKICBjb25zdCBvdXRwdXRFbGVtZW50ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQob3V0cHV0SWQpOwogIG91dHB1dEVsZW1lbnQuaW5uZXJIVE1MID0gJyc7CgogIGNvbnN0IHBpY2tlZFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgaW5wdXRFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIChlKSA9PiB7CiAgICAgIHJlc29sdmUoZS50YXJnZXQuZmlsZXMpOwogICAgfSk7CiAgfSk7CgogIGNvbnN0IGNhbmNlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpOwogIGlucHV0RWxlbWVudC5wYXJlbnRFbGVtZW50LmFwcGVuZENoaWxkKGNhbmNlbCk7CiAgY2FuY2VsLnRleHRDb250ZW50ID0gJ0NhbmNlbCB1cGxvYWQnOwogIGNvbnN0IGNhbmNlbFByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gewogICAgY2FuY2VsLm9uY2xpY2sgPSAoKSA9PiB7CiAgICAgIHJlc29sdmUobnVsbCk7CiAgICB9OwogIH0pOwoKICAvLyBXYWl0IGZvciB0aGUgdXNlciB0byBwaWNrIHRoZSBmaWxlcy4KICBjb25zdCBmaWxlcyA9IHlpZWxkIHsKICAgIHByb21pc2U6IFByb21pc2UucmFjZShbcGlja2VkUHJvbWlzZSwgY2FuY2VsUHJvbWlzZV0pLAogICAgcmVzcG9uc2U6IHsKICAgICAgYWN0aW9uOiAnc3RhcnRpbmcnLAogICAgfQogIH07CgogIGNhbmNlbC5yZW1vdmUoKTsKCiAgLy8gRGlzYWJsZSB0aGUgaW5wdXQgZWxlbWVudCBzaW5jZSBmdXJ0aGVyIHBpY2tzIGFyZSBub3QgYWxsb3dlZC4KICBpbnB1dEVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlOwoKICBpZiAoIWZpbGVzKSB7CiAgICByZXR1cm4gewogICAgICByZXNwb25zZTogewogICAgICAgIGFjdGlvbjogJ2NvbXBsZXRlJywKICAgICAgfQogICAgfTsKICB9CgogIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykgewogICAgY29uc3QgbGkgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaScpOwogICAgbGkuYXBwZW5kKHNwYW4oZmlsZS5uYW1lLCB7Zm9udFdlaWdodDogJ2JvbGQnfSkpOwogICAgbGkuYXBwZW5kKHNwYW4oCiAgICAgICAgYCgke2ZpbGUudHlwZSB8fCAnbi9hJ30pIC0gJHtmaWxlLnNpemV9IGJ5dGVzLCBgICsKICAgICAgICBgbGFzdCBtb2RpZmllZDogJHsKICAgICAgICAgICAgZmlsZS5sYXN0TW9kaWZpZWREYXRlID8gZmlsZS5sYXN0TW9kaWZpZWREYXRlLnRvTG9jYWxlRGF0ZVN0cmluZygpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ24vYSd9IC0gYCkpOwogICAgY29uc3QgcGVyY2VudCA9IHNwYW4oJzAlIGRvbmUnKTsKICAgIGxpLmFwcGVuZENoaWxkKHBlcmNlbnQpOwoKICAgIG91dHB1dEVsZW1lbnQuYXBwZW5kQ2hpbGQobGkpOwoKICAgIGNvbnN0IGZpbGVEYXRhUHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7CiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7CiAgICAgIHJlYWRlci5vbmxvYWQgPSAoZSkgPT4gewogICAgICAgIHJlc29sdmUoZS50YXJnZXQucmVzdWx0KTsKICAgICAgfTsKICAgICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGZpbGUpOwogICAgfSk7CiAgICAvLyBXYWl0IGZvciB0aGUgZGF0YSB0byBiZSByZWFkeS4KICAgIGxldCBmaWxlRGF0YSA9IHlpZWxkIHsKICAgICAgcHJvbWlzZTogZmlsZURhdGFQcm9taXNlLAogICAgICByZXNwb25zZTogewogICAgICAgIGFjdGlvbjogJ2NvbnRpbnVlJywKICAgICAgfQogICAgfTsKCiAgICAvLyBVc2UgYSBjaHVua2VkIHNlbmRpbmcgdG8gYXZvaWQgbWVzc2FnZSBzaXplIGxpbWl0cy4gU2VlIGIvNjIxMTU2NjAuCiAgICBsZXQgcG9zaXRpb24gPSAwOwogICAgd2hpbGUgKHBvc2l0aW9uIDwgZmlsZURhdGEuYnl0ZUxlbmd0aCkgewogICAgICBjb25zdCBsZW5ndGggPSBNYXRoLm1pbihmaWxlRGF0YS5ieXRlTGVuZ3RoIC0gcG9zaXRpb24sIE1BWF9QQVlMT0FEX1NJWkUpOwogICAgICBjb25zdCBjaHVuayA9IG5ldyBVaW50OEFycmF5KGZpbGVEYXRhLCBwb3NpdGlvbiwgbGVuZ3RoKTsKICAgICAgcG9zaXRpb24gKz0gbGVuZ3RoOwoKICAgICAgY29uc3QgYmFzZTY0ID0gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGNodW5rKSk7CiAgICAgIHlpZWxkIHsKICAgICAgICByZXNwb25zZTogewogICAgICAgICAgYWN0aW9uOiAnYXBwZW5kJywKICAgICAgICAgIGZpbGU6IGZpbGUubmFtZSwKICAgICAgICAgIGRhdGE6IGJhc2U2NCwKICAgICAgICB9LAogICAgICB9OwogICAgICBwZXJjZW50LnRleHRDb250ZW50ID0KICAgICAgICAgIGAke01hdGgucm91bmQoKHBvc2l0aW9uIC8gZmlsZURhdGEuYnl0ZUxlbmd0aCkgKiAxMDApfSUgZG9uZWA7CiAgICB9CiAgfQoKICAvLyBBbGwgZG9uZS4KICB5aWVsZCB7CiAgICByZXNwb25zZTogewogICAgICBhY3Rpb246ICdjb21wbGV0ZScsCiAgICB9CiAgfTsKfQoKc2NvcGUuZ29vZ2xlID0gc2NvcGUuZ29vZ2xlIHx8IHt9OwpzY29wZS5nb29nbGUuY29sYWIgPSBzY29wZS5nb29nbGUuY29sYWIgfHwge307CnNjb3BlLmdvb2dsZS5jb2xhYi5fZmlsZXMgPSB7CiAgX3VwbG9hZEZpbGVzLAogIF91cGxvYWRGaWxlc0NvbnRpbnVlLAp9Owp9KShzZWxmKTsK",
       "headers": [
        [
         "content-type",
         "application/javascript"
        ]
       ],
       "ok": true,
       "status": 200,
       "status_text": ""
      }
     }
    },
    "id": "CeV_m9KDeflM",
    "outputId": "55292090-d007-4c0b-d187-02b6612d830a"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting scipy\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/c8/89/63171228d5ced148f5ced50305c89e8576ffc695a90b58fe5bb602b910c2/scipy-1.5.4-cp36-cp36m-manylinux1_x86_64.whl (25.9MB)\n",
      "\u001b[K     |████████████████████████████████| 25.9MB 119kB/s \n",
      "\u001b[?25hCollecting torch_snippets\n",
      "  Downloading https://files.pythonhosted.org/packages/e5/57/7d513a66ffc00d1495c8a8eeac8754b42233d8a68aa565077db8939b0452/torch_snippets-0.235-py3-none-any.whl\n",
      "Collecting torch_summary\n",
      "  Downloading https://files.pythonhosted.org/packages/83/49/f9db57bcad7246591b93519fd8e5166c719548c45945ef7d2fc9fcba46fb/torch_summary-1.4.3-py3-none-any.whl\n",
      "Requirement already satisfied, skipping upgrade: numpy>=1.14.5 in /usr/local/lib/python3.6/dist-packages (from scipy) (1.18.5)\n",
      "Collecting opencv-python-headless\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/08/e9/57d869561389884136be65a2d1bc038fe50171e2ba348fda269a4aab8032/opencv_python_headless-4.4.0.46-cp36-cp36m-manylinux2014_x86_64.whl (36.7MB)\n",
      "\u001b[K     |████████████████████████████████| 36.7MB 89kB/s \n",
      "\u001b[?25hRequirement already satisfied, skipping upgrade: Pillow in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (7.0.0)\n",
      "Requirement already satisfied, skipping upgrade: matplotlib in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (3.2.2)\n",
      "Requirement already satisfied, skipping upgrade: tqdm in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (4.41.1)\n",
      "Requirement already satisfied, skipping upgrade: pandas in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (1.1.4)\n",
      "Collecting loguru\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/6d/48/0a7d5847e3de329f1d0134baf707b689700b53bd3066a5a8cfd94b3c9fc8/loguru-0.5.3-py3-none-any.whl (57kB)\n",
      "\u001b[K     |████████████████████████████████| 61kB 9.5MB/s \n",
      "\u001b[?25hRequirement already satisfied, skipping upgrade: dill in /usr/local/lib/python3.6/dist-packages (from torch_snippets) (0.3.3)\n",
      "Requirement already satisfied, skipping upgrade: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (2.4.7)\n",
      "Requirement already satisfied, skipping upgrade: kiwisolver>=1.0.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (1.3.1)\n",
      "Requirement already satisfied, skipping upgrade: cycler>=0.10 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (0.10.0)\n",
      "Requirement already satisfied, skipping upgrade: python-dateutil>=2.1 in /usr/local/lib/python3.6/dist-packages (from matplotlib->torch_snippets) (2.8.1)\n",
      "Requirement already satisfied, skipping upgrade: pytz>=2017.2 in /usr/local/lib/python3.6/dist-packages (from pandas->torch_snippets) (2018.9)\n",
      "Collecting aiocontextvars>=0.2.0; python_version < \"3.7\"\n",
      "  Downloading https://files.pythonhosted.org/packages/db/c1/7a723e8d988de0a2e623927396e54b6831b68cb80dce468c945b849a9385/aiocontextvars-0.2.2-py2.py3-none-any.whl\n",
      "Requirement already satisfied, skipping upgrade: six in /usr/local/lib/python3.6/dist-packages (from cycler>=0.10->matplotlib->torch_snippets) (1.15.0)\n",
      "Collecting contextvars==2.4; python_version < \"3.7\"\n",
      "  Downloading https://files.pythonhosted.org/packages/83/96/55b82d9f13763be9d672622e1b8106c85acb83edd7cc2fa5bc67cd9877e9/contextvars-2.4.tar.gz\n",
      "Collecting immutables>=0.9\n",
      "\u001b[?25l  Downloading https://files.pythonhosted.org/packages/99/e0/ea6fd4697120327d26773b5a84853f897a68e33d3f9376b00a8ff96e4f63/immutables-0.14-cp36-cp36m-manylinux1_x86_64.whl (98kB)\n",
      "\u001b[K     |████████████████████████████████| 102kB 14.1MB/s \n",
      "\u001b[?25hBuilding wheels for collected packages: contextvars\n",
      "  Building wheel for contextvars (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
      "  Created wheel for contextvars: filename=contextvars-2.4-cp36-none-any.whl size=7666 sha256=5976ad63e4d7be29f86455820048fd851c169bc1671ad4627743b2b16053a1e3\n",
      "  Stored in directory: /root/.cache/pip/wheels/a5/7d/68/1ebae2668bda2228686e3c1cf16f2c2384cea6e9334ad5f6de\n",
      "Successfully built contextvars\n",
      "\u001b[31mERROR: tensorflow 2.3.0 has requirement scipy==1.4.1, but you'll have scipy 1.5.4 which is incompatible.\u001b[0m\n",
      "\u001b[31mERROR: albumentations 0.1.12 has requirement imgaug<0.2.7,>=0.2.5, but you'll have imgaug 0.2.9 which is incompatible.\u001b[0m\n",
      "Installing collected packages: scipy, opencv-python-headless, immutables, contextvars, aiocontextvars, loguru, torch-snippets, torch-summary\n",
      "  Found existing installation: scipy 1.4.1\n",
      "    Uninstalling scipy-1.4.1:\n",
      "      Successfully uninstalled scipy-1.4.1\n",
      "Successfully installed aiocontextvars-0.2.2 contextvars-2.4 immutables-0.14 loguru-0.5.3 opencv-python-headless-4.4.0.46 scipy-1.5.4 torch-snippets-0.235 torch-summary-1.4.3\n",
      "Cloning into 'CSRNet-pytorch'...\n",
      "remote: Enumerating objects: 6, done.\u001b[K\n",
      "remote: Counting objects: 100% (6/6), done.\u001b[K\n",
      "remote: Compressing objects: 100% (6/6), done.\u001b[K\n",
      "remote: Total 92 (delta 1), reused 0 (delta 0), pack-reused 86\u001b[K\n",
      "Unpacking objects: 100% (92/92), done.\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "\n",
       "     <input type=\"file\" id=\"files-729ef6ce-1e92-4798-b82c-f4666925830b\" name=\"files[]\" multiple disabled\n",
       "        style=\"border:none\" />\n",
       "     <output id=\"result-729ef6ce-1e92-4798-b82c-f4666925830b\">\n",
       "      Upload widget is only available when the cell has been executed in the\n",
       "      current browser session. Please rerun this cell to enable.\n",
       "      </output>\n",
       "      <script src=\"/nbextensions/google.colab/files.js\"></script> "
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Saving kaggle.json to kaggle.json\n",
      "kaggle.json\n",
      "downloading data...\n",
      "Downloading shanghaitech-with-people-density-map.zip to /content\n",
      "100% 4.78G/4.79G [01:37<00:00, 41.5MB/s]\n",
      "100% 4.79G/4.79G [01:37<00:00, 52.6MB/s]\n",
      "unzipping data...\n",
      "/content/CSRNet-pytorch\n",
      "CPU times: user 1.64 s, sys: 431 ms, total: 2.07 s\n",
      "Wall time: 5min 34s\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "import os\n",
    "if not os.path.exists('CSRNet-pytorch/'):\n",
    "    !pip install -U scipy torch_snippets torch_summary\n",
    "    !git clone https://github.com/sizhky/CSRNet-pytorch.git\n",
    "    from google.colab import files\n",
    "    files.upload() # upload kaggle.json\n",
    "    !mkdir -p ~/.kaggle\n",
    "    !mv kaggle.json ~/.kaggle/\n",
    "    !ls ~/.kaggle\n",
    "    !chmod 600 /root/.kaggle/kaggle.json\n",
    "    print('downloading data...')\n",
    "    !kaggle datasets download -d tthien/shanghaitech-with-people-density-map/\n",
    "    print('unzipping data...')\n",
    "    !unzip -qq shanghaitech-with-people-density-map.zip\n",
    "\n",
    "%cd CSRNet-pytorch\n",
    "!ln -s ../shanghaitech_with_people_density_map\n",
    "from torch_snippets import *\n",
    "import h5py\n",
    "from scipy import io"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "E_IKzYrMejRN",
    "outputId": "1456d52e-538c-4842-e2c0-f2582d25145f"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2020-11-08 10:55:51.544 | INFO     | torch_snippets.loader:Glob:181 - 3 files found at shanghaitech_with_people_density_map/ShanghaiTech/part_A/train_data/\n"
     ]
    }
   ],
   "source": [
    "part_A = Glob('shanghaitech_with_people_density_map/ShanghaiTech/part_A/train_data/');\n",
    "\n",
    "image_folder = 'shanghaitech_with_people_density_map/ShanghaiTech/part_A/train_data/images/'\n",
    "heatmap_folder = 'shanghaitech_with_people_density_map/ShanghaiTech/part_A/train_data/ground-truth-h5/'\n",
    "gt_folder = 'shanghaitech_with_people_density_map/ShanghaiTech/part_A/train_data/ground-truth/'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "gvmHy_SQe3Jz",
    "outputId": "eb879e1d-83b9-467e-e9e3-9e4556c9cee8"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2020-11-08 10:55:53.547 | INFO     | torch_snippets.loader:Glob:181 - 300 files found at shanghaitech_with_people_density_map/ShanghaiTech/part_A/train_data/images/\n"
     ]
    }
   ],
   "source": [
    "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n",
    "tfm = T.Compose([\n",
    "    T.ToTensor()\n",
    "])\n",
    "\n",
    "class Crowds(Dataset):\n",
    "    def __init__(self, stems):\n",
    "        self.stems = stems\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.stems)\n",
    "\n",
    "    def __getitem__(self, ix):\n",
    "        _stem = self.stems[ix]\n",
    "        image_path = f'{image_folder}/{_stem}.jpg'\n",
    "        heatmap_path = f'{heatmap_folder}/{_stem}.h5'\n",
    "        gt_path = f'{gt_folder}/GT_{_stem}.mat'\n",
    "\n",
    "        pts = io.loadmat(gt_path)\n",
    "        pts = len(pts['image_info'][0,0][0,0][0])\n",
    "\n",
    "        image = read(image_path, 1)\n",
    "        with h5py.File(heatmap_path, 'r') as hf:\n",
    "            gt = hf['density'][:]\n",
    "        gt = resize(gt, 1/8)*64\n",
    "        return image.copy(), gt.copy(), pts\n",
    "\n",
    "    def collate_fn(self, batch):\n",
    "        ims, gts, pts = list(zip(*batch))\n",
    "        ims = torch.cat([tfm(im)[None] for im in ims]).to(device)\n",
    "        gts = torch.cat([tfm(gt)[None] for gt in gts]).to(device)\n",
    "        return ims, gts, torch.tensor(pts).to(device)\n",
    "\n",
    "    def choose(self):\n",
    "        return self[randint(len(self))]\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "trn_stems, val_stems = train_test_split(stems(Glob(image_folder)), random_state=10)\n",
    "\n",
    "trn_ds = Crowds(trn_stems)\n",
    "val_ds = Crowds(val_stems)\n",
    "\n",
    "trn_dl = DataLoader(trn_ds, batch_size=1, shuffle=True, collate_fn=trn_ds.collate_fn)\n",
    "val_dl = DataLoader(val_ds, batch_size=1, shuffle=True, collate_fn=val_ds.collate_fn)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "QqigjcrEe7RZ"
   },
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch\n",
    "from torchvision import models\n",
    "from utils import save_net,load_net\n",
    "\n",
    "def make_layers(cfg, in_channels = 3,batch_norm=False,dilation = False):\n",
    "    if dilation:\n",
    "        d_rate = 2\n",
    "    else:\n",
    "        d_rate = 1\n",
    "    layers = []\n",
    "    for v in cfg:\n",
    "        if v == 'M':\n",
    "            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]\n",
    "        else:\n",
    "            conv2d = nn.Conv2d(in_channels, v, kernel_size=3, padding=d_rate, dilation=d_rate)\n",
    "            if batch_norm:\n",
    "                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]\n",
    "            else:\n",
    "                layers += [conv2d, nn.ReLU(inplace=True)]\n",
    "            in_channels = v\n",
    "    return nn.Sequential(*layers)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "VWN1CvrmfMfz"
   },
   "outputs": [],
   "source": [
    "class CSRNet(nn.Module):\n",
    "    def __init__(self, load_weights=False):\n",
    "        super(CSRNet, self).__init__()\n",
    "        self.seen = 0\n",
    "        self.frontend_feat = [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512]\n",
    "        self.backend_feat = [512, 512, 512, 256, 128, 64]\n",
    "        self.frontend = make_layers(self.frontend_feat)\n",
    "        self.backend = make_layers(self.backend_feat,in_channels = 512,dilation = True)\n",
    "        self.output_layer = nn.Conv2d(64, 1, kernel_size=1)\n",
    "        if not load_weights:\n",
    "            mod = models.vgg16(pretrained = True)\n",
    "            self._initialize_weights()\n",
    "            items = list(self.frontend.state_dict().items())\n",
    "            _items = list(mod.state_dict().items())\n",
    "            for i in range(len(self.frontend.state_dict().items())):\n",
    "                items[i][1].data[:] = _items[i][1].data[:]\n",
    "    def forward(self,x):\n",
    "        x = self.frontend(x)\n",
    "        x = self.backend(x)\n",
    "        x = self.output_layer(x)\n",
    "        return x\n",
    "    def _initialize_weights(self):\n",
    "        for m in self.modules():\n",
    "            if isinstance(m, nn.Conv2d):\n",
    "                nn.init.normal_(m.weight, std=0.01)\n",
    "                if m.bias is not None:\n",
    "                    nn.init.constant_(m.bias, 0)\n",
    "            elif isinstance(m, nn.BatchNorm2d):\n",
    "                nn.init.constant_(m.weight, 1)\n",
    "                nn.init.constant_(m.bias, 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "FlbtdBNdfShx"
   },
   "outputs": [],
   "source": [
    "def train_batch(model, data, optimizer, criterion):\n",
    "    model.train()\n",
    "    optimizer.zero_grad()\n",
    "    ims, gts, pts = data\n",
    "    _gts = model(ims)\n",
    "    loss = criterion(_gts, gts)\n",
    "    loss.backward()\n",
    "    optimizer.step()\n",
    "    pts_loss = nn.L1Loss()(_gts.sum(), gts.sum())\n",
    "    return loss.item(), pts_loss.item()\n",
    "\n",
    "@torch.no_grad()\n",
    "def validate_batch(model, data, criterion):\n",
    "    model.eval()\n",
    "    ims, gts, pts = data\n",
    "    _gts = model(ims)\n",
    "    loss = criterion(_gts, gts)\n",
    "    pts_loss = nn.L1Loss()(_gts.sum(), gts.sum())\n",
    "    return loss.item(), pts_loss.item()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 423,
     "referenced_widgets": [
      "aede6677adff4a2c9c554f27ff78b674",
      "da6f58f74e2749788709dbf45315d0e0",
      "f65d94cedfb84673a55b0b6c95f7587f",
      "5f90fa368ae140888ff1e9f32c1168cb",
      "f353954c306143b0b3aa0efbc6b9c5c6",
      "573ec2c22a4f443d8d7e310b88bbc4b4",
      "b68a749a35974a1fad0d74bccc04e771",
      "414d6bd452c7452597388ee0b57e3df2"
     ]
    },
    "id": "4TohVvEOfS0L",
    "outputId": "cc885c5f-57d7-4ca2-9c09-68ed7dad7cb5"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Downloading: \"https://download.pytorch.org/models/vgg16-397923af.pth\" to /root/.cache/torch/hub/checkpoints/vgg16-397923af.pth\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "aede6677adff4a2c9c554f27ff78b674",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(FloatProgress(value=0.0, max=553433881.0), HTML(value='')))"
      ]
     },
     "metadata": {
      "tags": []
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "EPOCH: 1.000\ttrn_loss: 0.048\ttrn_pts_loss: 427.918\tval_loss: 0.053\tval_pts_loss: 347.524\t(77.39s - 1470.45s remaining)\n",
      "EPOCH: 2.000\ttrn_loss: 0.042\ttrn_pts_loss: 306.686\tval_loss: 0.048\tval_pts_loss: 262.405\t(154.97s - 1394.71s remaining)\n",
      "EPOCH: 3.000\ttrn_loss: 0.036\ttrn_pts_loss: 204.923\tval_loss: 0.043\tval_pts_loss: 190.447\t(232.47s - 1317.31s remaining)\n",
      "EPOCH: 4.000\ttrn_loss: 0.033\ttrn_pts_loss: 159.764\tval_loss: 0.042\tval_pts_loss: 184.419\t(310.06s - 1240.24s remaining)\n",
      "EPOCH: 5.000\ttrn_loss: 0.032\ttrn_pts_loss: 145.682\tval_loss: 0.041\tval_pts_loss: 241.129\t(387.48s - 1162.44s remaining)\n",
      "EPOCH: 6.000\ttrn_loss: 0.031\ttrn_pts_loss: 139.674\tval_loss: 0.039\tval_pts_loss: 172.444\t(464.97s - 1084.93s remaining)\n",
      "EPOCH: 7.000\ttrn_loss: 0.031\ttrn_pts_loss: 143.573\tval_loss: 0.039\tval_pts_loss: 154.602\t(542.31s - 1007.15s remaining)\n",
      "EPOCH: 8.000\ttrn_loss: 0.030\ttrn_pts_loss: 126.261\tval_loss: 0.038\tval_pts_loss: 152.646\t(619.65s - 929.47s remaining)\n",
      "EPOCH: 9.000\ttrn_loss: 0.030\ttrn_pts_loss: 121.418\tval_loss: 0.036\tval_pts_loss: 168.236\t(696.97s - 851.86s remaining)\n",
      "EPOCH: 10.000\ttrn_loss: 0.029\ttrn_pts_loss: 122.989\tval_loss: 0.039\tval_pts_loss: 183.355\t(774.30s - 774.30s remaining)\n",
      "EPOCH: 11.000\ttrn_loss: 0.029\ttrn_pts_loss: 121.840\tval_loss: 0.038\tval_pts_loss: 198.861\t(851.56s - 696.73s remaining)\n",
      "EPOCH: 12.000\ttrn_loss: 0.029\ttrn_pts_loss: 123.117\tval_loss: 0.032\tval_pts_loss: 131.696\t(928.88s - 619.26s remaining)\n",
      "EPOCH: 13.000\ttrn_loss: 0.029\ttrn_pts_loss: 117.252\tval_loss: 0.041\tval_pts_loss: 145.208\t(1006.07s - 541.73s remaining)\n",
      "EPOCH: 14.000\ttrn_loss: 0.028\ttrn_pts_loss: 110.343\tval_loss: 0.036\tval_pts_loss: 134.451\t(1083.44s - 464.33s remaining)\n",
      "EPOCH: 15.000\ttrn_loss: 0.028\ttrn_pts_loss: 113.773\tval_loss: 0.036\tval_pts_loss: 182.355\t(1160.97s - 386.99s remaining)\n",
      "EPOCH: 16.000\ttrn_loss: 0.028\ttrn_pts_loss: 109.048\tval_loss: 0.036\tval_pts_loss: 152.386\t(1238.67s - 309.67s remaining)\n",
      "EPOCH: 17.000\ttrn_loss: 0.028\ttrn_pts_loss: 107.314\tval_loss: 0.035\tval_pts_loss: 139.919\t(1316.50s - 232.32s remaining)\n",
      "EPOCH: 18.000\ttrn_loss: 0.028\ttrn_pts_loss: 111.054\tval_loss: 0.036\tval_pts_loss: 133.333\t(1394.37s - 154.93s remaining)\n",
      "EPOCH: 19.000\ttrn_loss: 0.027\ttrn_pts_loss: 110.610\tval_loss: 0.036\tval_pts_loss: 141.666\t(1472.28s - 77.49s remaining)\n",
      "EPOCH: 20.000\ttrn_loss: 0.028\ttrn_pts_loss: 113.707\tval_loss: 0.034\tval_pts_loss: 167.978\t(1550.17s - 0.00s remaining)\n"
     ]
    }
   ],
   "source": [
    "model = CSRNet().to(device)\n",
    "criterion = nn.MSELoss()\n",
    "optimizer = optim.Adam(model.parameters(), lr=1e-6)\n",
    "n_epochs = 20\n",
    "\n",
    "log = Report(n_epochs)\n",
    "for ex in range(n_epochs):\n",
    "    N = len(trn_dl)\n",
    "    for bx, data in enumerate(trn_dl):\n",
    "        loss, pts_loss = train_batch(model, data, optimizer, criterion)\n",
    "        log.record(ex+(bx+1)/N, trn_loss=loss, trn_pts_loss=pts_loss, end='\\r')\n",
    "\n",
    "    N = len(val_dl)\n",
    "    for bx, data in enumerate(val_dl):\n",
    "        loss, pts_loss = validate_batch(model, data, criterion)\n",
    "        log.record(ex+(bx+1)/N, val_loss=loss, val_pts_loss=pts_loss, end='\\r')\n",
    "\n",
    "    log.report_avgs(ex+1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "OsWAQDqKfZel",
    "outputId": "8780ed15-c913-4fb6-f9cd-b7417927f303"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2020-11-08 11:30:25.780 | INFO     | torch_snippets.loader:Glob:181 - 182 files found at shanghaitech_with_people_density_map/ShanghaiTech/part_A/test_data//images\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "shanghaitech_with_people_density_map/ShanghaiTech/part_A/test_data//images/IMG_4.jpg\n"
     ]
    }
   ],
   "source": [
    "from matplotlib import cm as c\n",
    "from torchvision import datasets, transforms\n",
    "from PIL import Image\n",
    "transform=transforms.Compose([\n",
    "                      transforms.ToTensor(),transforms.Normalize(\n",
    "                          mean=[0.485, 0.456, 0.406],\n",
    "                          std=[0.229, 0.224, 0.225]),\n",
    "                  ])\n",
    "\n",
    "test_folder = 'shanghaitech_with_people_density_map/ShanghaiTech/part_A/test_data/'\n",
    "imgs = Glob(f'{test_folder}/images')\n",
    "f = choose(imgs)\n",
    "print(f)\n",
    "img = transform(Image.open(f).convert('RGB')).to(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 284
    },
    "id": "ejyqFvXOnxj9",
    "outputId": "e2ee0567-a90b-41bb-e4a0-d90c427d1eba"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Predicted Count :  183\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light",
      "tags": []
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "output = model(img[None])\n",
    "print(\"Predicted Count : \",int(output.detach().cpu().sum().numpy()))\n",
    "temp = np.asarray(output.detach().cpu().reshape(output.detach().cpu().shape[2],output.detach().cpu().shape[3]))\n",
    "plt.imshow(temp,cmap = c.jet)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "gduPbtJwny8z"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "include_colab_link": true,
   "name": "corwd_counting.ipynb",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.2"
  },
  "widgets": {
   "application/vnd.jupyter.widget-state+json": {
    "414d6bd452c7452597388ee0b57e3df2": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "573ec2c22a4f443d8d7e310b88bbc4b4": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "5f90fa368ae140888ff1e9f32c1168cb": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HTMLModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HTMLModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HTMLView",
      "description": "",
      "description_tooltip": null,
      "layout": "IPY_MODEL_414d6bd452c7452597388ee0b57e3df2",
      "placeholder": "​",
      "style": "IPY_MODEL_b68a749a35974a1fad0d74bccc04e771",
      "value": " 528M/528M [00:02&lt;00:00, 231MB/s]"
     }
    },
    "aede6677adff4a2c9c554f27ff78b674": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "HBoxModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "HBoxModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "HBoxView",
      "box_style": "",
      "children": [
       "IPY_MODEL_f65d94cedfb84673a55b0b6c95f7587f",
       "IPY_MODEL_5f90fa368ae140888ff1e9f32c1168cb"
      ],
      "layout": "IPY_MODEL_da6f58f74e2749788709dbf45315d0e0"
     }
    },
    "b68a749a35974a1fad0d74bccc04e771": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "DescriptionStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "DescriptionStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "description_width": ""
     }
    },
    "da6f58f74e2749788709dbf45315d0e0": {
     "model_module": "@jupyter-widgets/base",
     "model_name": "LayoutModel",
     "state": {
      "_model_module": "@jupyter-widgets/base",
      "_model_module_version": "1.2.0",
      "_model_name": "LayoutModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "LayoutView",
      "align_content": null,
      "align_items": null,
      "align_self": null,
      "border": null,
      "bottom": null,
      "display": null,
      "flex": null,
      "flex_flow": null,
      "grid_area": null,
      "grid_auto_columns": null,
      "grid_auto_flow": null,
      "grid_auto_rows": null,
      "grid_column": null,
      "grid_gap": null,
      "grid_row": null,
      "grid_template_areas": null,
      "grid_template_columns": null,
      "grid_template_rows": null,
      "height": null,
      "justify_content": null,
      "justify_items": null,
      "left": null,
      "margin": null,
      "max_height": null,
      "max_width": null,
      "min_height": null,
      "min_width": null,
      "object_fit": null,
      "object_position": null,
      "order": null,
      "overflow": null,
      "overflow_x": null,
      "overflow_y": null,
      "padding": null,
      "right": null,
      "top": null,
      "visibility": null,
      "width": null
     }
    },
    "f353954c306143b0b3aa0efbc6b9c5c6": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "ProgressStyleModel",
     "state": {
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "ProgressStyleModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/base",
      "_view_module_version": "1.2.0",
      "_view_name": "StyleView",
      "bar_color": null,
      "description_width": "initial"
     }
    },
    "f65d94cedfb84673a55b0b6c95f7587f": {
     "model_module": "@jupyter-widgets/controls",
     "model_name": "FloatProgressModel",
     "state": {
      "_dom_classes": [],
      "_model_module": "@jupyter-widgets/controls",
      "_model_module_version": "1.5.0",
      "_model_name": "FloatProgressModel",
      "_view_count": null,
      "_view_module": "@jupyter-widgets/controls",
      "_view_module_version": "1.5.0",
      "_view_name": "ProgressView",
      "bar_style": "success",
      "description": "100%",
      "description_tooltip": null,
      "layout": "IPY_MODEL_573ec2c22a4f443d8d7e310b88bbc4b4",
      "max": 553433881,
      "min": 0,
      "orientation": "horizontal",
      "style": "IPY_MODEL_f353954c306143b0b3aa0efbc6b9c5c6",
      "value": 553433881
     }
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
